package com.gsbelarus.gedemin.salary.util;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.preference.PreferenceManager;
import android.util.Log;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.gcm.GoogleCloudMessaging;
import com.gsbelarus.gedemin.salary.database.RealmHelper;
import com.gsbelarus.gedemin.salary.entity.model.SyncInfoModel;
import com.gsbelarus.gedemin.salary.fragment.SettingsFragment;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;

import io.realm.Realm;

public class GCMHelper {

    private static final int START_DELAY = 5 * 1000;

    private static final String SENDER_ID = "303114121834";

    private Context context;
    private SharedPreferences prefs;

    public GCMHelper(Context context) {
        this.context = context;
        prefs = PreferenceManager.getDefaultSharedPreferences(context);
    }

    public void checkRegistration() {
        RealmHelper realmHelper = new RealmHelper(Realm.getInstance(context));
        SyncInfoModel syncInfo = realmHelper.getSyncInfo(true);
        if (syncInfo == null || syncInfo.getEmplId() == null || !checkPlayServices()) return;

        if (getRegistrationId(realmHelper).isEmpty())
            updateRegistration();
        realmHelper.getRealm().close();
    }

    public void updateRegistration() {
        new AsyncTask<Void, Void, Void>() {

            @Override
            protected Void doInBackground(Void... params) {
                boolean repeat = true;

                int repeatDelay = START_DELAY;
                RealmHelper realmHelper = new RealmHelper(Realm.getInstance(context));
                while (repeat) {
                    try {
                        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context);
                        String regid = gcm.register(SENDER_ID);
                        Log.i(GCMHelper.class.getSimpleName(), "Device registered, registration ID=" + regid);

                        if (!getRegistrationId(realmHelper).equals(regid)) {
                            storeRegistrationId(realmHelper, "");
                            if (sendRegistrationIdToBackend(realmHelper, regid)) {
                                storeRegistrationId(realmHelper, regid);
                                Log.i(GCMHelper.class.getSimpleName(), "Registration ID sent to the server");
                            }
                        }

                        repeat = false;

                    } catch (Exception ex) {
                        //Crashlytics.getInstance().core.logException(ex);
                        if (!ex.getMessage().equals(GoogleCloudMessaging.ERROR_SERVICE_NOT_AVAILABLE))
                            repeat = false;
                        else {
                            try {
                                Thread.sleep(repeatDelay);
                                repeatDelay *= 2;
                            } catch (InterruptedException e) {
                                //Crashlytics.getInstance().core.logException(e);
                                repeat = false;
                                Log.i(GCMHelper.class.getSimpleName(), "Error : " + e.getMessage());
                            }
                        }
                        Log.i(GCMHelper.class.getSimpleName(), "Error : " + ex.getMessage());
                    }
                }
                realmHelper.getRealm().close();
                return null;
            }
        }.execute();
    }

    private boolean sendRegistrationIdToBackend(RealmHelper realmHelper, String regid) {
        SyncInfoModel syncInfo = realmHelper.getSyncInfo(true);
        if (regid.isEmpty() || syncInfo.getEmplId().isEmpty() || syncInfo.getLastSyncKey().isEmpty())
            return false;

        String urlString = "http://" + prefs.getString(SettingsFragment.ADDRESS_SERVER, "") +
                "?token=gdmnSalarySetGCMRegId" +
                "&sync_key=" + syncInfo.getLastSyncKey() +
                "&gcm_reg_id=" + regid;
        try {
            URL url = new URL(urlString);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setConnectTimeout(3000);
            connection.setReadTimeout(3000);
            connection.connect();

            connection.disconnect();
            return true;

        } catch (IOException e) {
            //Crashlytics.getInstance().core.logException(e);
            Log.i(GCMHelper.class.getSimpleName(), e.toString());
        }
        return false;
    }

    private String getRegistrationId(RealmHelper realmHelper) {
        SyncInfoModel syncInfo = realmHelper.getSyncInfo(true);
        String registrationId = syncInfo.getGcmRegistrationId();
        if (registrationId == null || registrationId.isEmpty()) {
            Log.i(GCMHelper.class.getSimpleName(), "Registration not found.");
            return "";
        }
        return registrationId;
    }

    private void storeRegistrationId(RealmHelper realmHelper, String regId) {
        realmHelper.getRealm().beginTransaction();
        realmHelper.getSyncInfo(false).setGcmRegistrationId(regId);
        realmHelper.getRealm().commitTransaction();
    }

    public boolean checkPlayServices(Activity activity) {
        int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(context);
        if (resultCode != ConnectionResult.SUCCESS) {
            if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
                GooglePlayServicesUtil.getErrorDialog(resultCode, activity,
                        9000).show();
            } else {
                Log.i(GCMHelper.class.getSimpleName(), "This device is not supported.");
                activity.finish();
            }
            return false;
        }
        return true;
    }

    public boolean checkPlayServices() {
        int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(context);
        return resultCode == ConnectionResult.SUCCESS;
    }
}
